library(magick)
flag_img <- magick::image_read("data/flag.png")
# plot(flag_img)
flag_img %>%
image_resize("50%")reset
이미지 인식library(keras)
# 이미지 데이터를 TF 넣을 수 있는 `array` 형태로 변환
flag_img <- image_load("data/flag.png", target_size = c(224,224))
x <- image_to_array(flag_img)
x <- array_reshape(x, c(1, dim(x)))
x <- imagenet_preprocess_input(x)
resnet50_pretrained <- application_resnet50(weights = "imagenet")
preds <- resnet50_pretrained %>%
predict(x) %>%
imagenet_decode_predictions(top = 5) %>%
.[[1]]
preds class_name class_description score
1 n03355925 flagpole 0.48924446
2 n03888257 parachute 0.15634954
3 n06359193 web_site 0.06883045
4 n04592741 wing 0.03475185
5 n03958227 plastic_bag 0.02852455
data <- dataset_cifar10()
trainx <- data$train$x
testx <- data$test$x
trainy <- to_categorical(data$train$y, num_classes = 10)
testy <- to_categorical(data$test$y, num_classes = 10)이미지 학습용으로 CIFAR-10은 32 x 32 크기의 60,000개의 이미지로 10개 범주로 나눠져 구성되어 있다. 즉, 10개의 범주로 나눠지고 각 범주는 6,000개로 분류되어 있다.
| Y 라벨 | 이미지 분류 |
|---|---|
| 0 | Airplane |
| 1 | Automobile |
| 2 | Bird |
| 3 | Cat |
| 4 | Deer |
| 5 | Dog |
| 6 | Frog |
| 7 | Horse |
| 8 | Ship |
| 9 | Truck |
cifar_7 <- list()
for(i in 1:7) {
cifar_7[[i]] <- magick::image_read(trainx[i,,,] / 255)
}
cifar_7 %>%
image_join() %>%
image_append(stack = FALSE) %>%
image_resize("400%")library(keras)
resnet50_pretrained <- application_resnet50(weights = "imagenet")
predict_image <- function(input_img) {
x <- image_array_resize(input_img, w = 224, h = 224)
x <- array_reshape(x, c(1, dim(x)))
x <- imagenet_preprocess_input(x)
preds <- resnet50_pretrained %>%
predict(x) %>%
imagenet_decode_predictions(top = 1) %>%
.[[1]] %>%
dplyr::pull(class_description)
return(preds)
}
image_names <- NULL
for(i in 1:7 ) {
image_names[i] <- predict_image(trainx[i,,,])
}
image_names[1] "macaque" "moving_van" "thresher" "hartebeest" "moving_van"
[6] "chain_saw" "limpkin"
cifar_7_names <- cifar_7 %>%
image_join() %>%
image_resize("600%") %>%
image_annotate(text = image_names, size = 30, location = "+50+0", degrees =45)
cifar_7_names %>%
image_append(stack = FALSE) data <- dataset_cifar10()
trainx <- data$train$x[1:1000,,,]
testx <- data$test$x[1:1000,,,]
trainy <- to_categorical(data$train$y[1:1000,], num_classes = 10)
testy <- to_categorical(data$test$y[1:1000,], num_classes = 10)
# 훈련 입력 이미지를 resent에 맞춰 224x224 으로 크기 조정
x <- array(rep(0, 1000 * 224 * 224 * 3), dim = c(1000, 224, 224, 3))
for (i in 1:1000) {
x[i,,,] <- image_array_resize(trainx[i,,,], 224, 224)
}
trainx <- imagenet_preprocess_input(x)
# 시험 입력 이미지를 resent에 맞춰 224x224 으로 크기 조정
x <- array(rep(0, 1000 * 224 * 224 * 3), dim = c(1000, 224, 224, 3))
for (i in 1:1000) {
x[i,,,] <- image_array_resize(testx[i,,,], 224, 224)
}
testx <- imagenet_preprocess_input(x)# Model architecture
model <- keras_model_sequential()
model %>%
layer_conv_2d(filters = 32, kernel_size = c(3,3), activation = 'relu',
input_shape = c(224,224,3)) %>%
layer_conv_2d(filters = 32, kernel_size = c(3,3), activation = 'relu') %>%
layer_max_pooling_2d(pool_size = c(2,2)) %>%
layer_dropout(rate = 0.25) %>%
layer_flatten() %>%
layer_dense(units = 256, activation = 'relu') %>%
layer_dropout(rate = 0.25) %>%
layer_dense(units = 10, activation = 'softmax')
summary(model)Model: "sequential"
________________________________________________________________________________
Layer (type) Output Shape Param #
================================================================================
conv2d_1 (Conv2D) (None, 222, 222, 32) 896
________________________________________________________________________________
conv2d (Conv2D) (None, 220, 220, 32) 9248
________________________________________________________________________________
max_pooling2d (MaxPooling2D) (None, 110, 110, 32) 0
________________________________________________________________________________
dropout_1 (Dropout) (None, 110, 110, 32) 0
________________________________________________________________________________
flatten (Flatten) (None, 387200) 0
________________________________________________________________________________
dense_1 (Dense) (None, 256) 99123456
________________________________________________________________________________
dropout (Dropout) (None, 256) 0
________________________________________________________________________________
dense (Dense) (None, 10) 2570
================================================================================
Total params: 99,136,170
Trainable params: 99,136,170
Non-trainable params: 0
________________________________________________________________________________
# 컴파일
model %>% compile(loss = 'categorical_crossentropy',
optimizer = 'rmsprop',
metrics = 'accuracy')
# 모형 적합
model_cnn <- model %>% fit(trainx,
trainy,
epochs = 10,
batch_size = 10,
validation_split = 0.2)
model_cnn2022-06-27 17:22:51.530824: W tensorflow/core/framework/cpu_allocator_impl.cc:81] Allocation of 396492800 exceeds 10% of free system memory.
2022-06-27 17:22:52.366457: W tensorflow/core/framework/cpu_allocator_impl.cc:81] Allocation of 396492800 exceeds 10% of free system memory.
Epoch 1/10
80/80 [==============================] - 152s 2s/step - loss: 222.3463 - accuracy: 0.1713 - val_loss: 2.2358 - val_accuracy: 0.2150
Epoch 2/10
80/80 [==============================] - 154s 2s/step - loss: 2.3729 - accuracy: 0.4412 - val_loss: 2.5260 - val_accuracy: 0.2750
Epoch 3/10
80/80 [==============================] - 143s 2s/step - loss: 1.1362 - accuracy: 0.7613 - val_loss: 3.1178 - val_accuracy: 0.2500
Epoch 4/10
80/80 [==============================] - 147s 2s/step - loss: 2.1652 - accuracy: 0.8763 - val_loss: 5.2696 - val_accuracy: 0.2500
Epoch 5/10
80/80 [==============================] - 150s 2s/step - loss: 0.9931 - accuracy: 0.9375 - val_loss: 49.1674 - val_accuracy: 0.1500
Epoch 6/10
80/80 [==============================] - 146s 2s/step - loss: 4.1380 - accuracy: 0.9038 - val_loss: 8.8890 - val_accuracy: 0.2250
Epoch 7/10
80/80 [==============================] - 136s 2s/step - loss: 0.8670 - accuracy: 0.9575 - val_loss: 16.6223 - val_accuracy: 0.2900
Epoch 8/10
80/80 [==============================] - 136s 2s/step - loss: 2.2269 - accuracy: 0.9312 - val_loss: 17.0739 - val_accuracy: 0.2000
Epoch 9/10
80/80 [==============================] - 137s 2s/step - loss: 11.1061 - accuracy: 0.9388 - val_loss: 19.4581 - val_accuracy: 0.2450
Epoch 10/10
80/80 [==============================] - 150s 2s/step - loss: 0.7317 - accuracy: 0.9700 - val_loss: 17.7526 - val_accuracy: 0.2200
Final epoch (plot to see history):
loss: 0.7317
accuracy: 0.97
val_loss: 17.75
val_accuracy: 0.22 # RESNET50
pretrained <- application_resnet50(weights = "imagenet",
include_top = FALSE,
input_shape = c(224, 224, 3))
model <- keras_model_sequential() %>%
pretrained %>%
layer_flatten() %>%
layer_dense(units = 256, activation = "relu") %>%
layer_dense(units = 10, activation = "softmax")
summary(model)Model: "sequential_1"
_____________________________________________________________________
Layer (type) Output Shape Param #
=====================================================================
resnet50 (Functional) (None, 7, 7, 2048) 23587712
_____________________________________________________________________
flatten_1 (Flatten) (None, 100352) 0
_____________________________________________________________________
dense_3 (Dense) (None, 256) 25690368
_____________________________________________________________________
dense_2 (Dense) (None, 10) 2570
=====================================================================
Total params: 49,280,650
Trainable params: 49,227,530
Non-trainable params: 53,120
_____________________________________________________________________
# Freeze weights of resnet50 network
freeze_weights(pretrained)
# Compile
model %>% compile(loss = 'categorical_crossentropy',
optimizer = 'rmsprop',
metrics = 'accuracy')
summary(model)Model: "sequential_1"
_____________________________________________________________________
Layer (type) Output Shape Param #
=====================================================================
resnet50 (Functional) (None, 7, 7, 2048) 23587712
_____________________________________________________________________
flatten_1 (Flatten) (None, 100352) 0
_____________________________________________________________________
dense_3 (Dense) (None, 256) 25690368
_____________________________________________________________________
dense_2 (Dense) (None, 10) 2570
=====================================================================
Total params: 49,280,650
Trainable params: 25,692,938
Non-trainable params: 23,587,712
_____________________________________________________________________
# Fit model
model_resnet50 <- model %>% fit(trainx,
trainy,
epochs = 10,
batch_size = 10,
validation_split = 0.2)
model_resnet50Epoch 1/10
80/80 [==============================] - 81s 1s/step - loss: 20.1118 - accuracy: 0.5863 - val_loss: 6.8605 - val_accuracy: 0.6700
Epoch 2/10
80/80 [==============================] - 83s 1s/step - loss: 2.1866 - accuracy: 0.8763 - val_loss: 6.7808 - val_accuracy: 0.7100
Epoch 3/10
80/80 [==============================] - 84s 1s/step - loss: 0.9900 - accuracy: 0.9275 - val_loss: 8.5960 - val_accuracy: 0.7000
Epoch 4/10
80/80 [==============================] - 83s 1s/step - loss: 0.9558 - accuracy: 0.9375 - val_loss: 6.4063 - val_accuracy: 0.8050
Epoch 5/10
80/80 [==============================] - 80s 1000ms/step - loss: 0.4001 - accuracy: 0.9675 - val_loss: 5.9686 - val_accuracy: 0.7850
Epoch 6/10
80/80 [==============================] - 78s 973ms/step - loss: 0.6653 - accuracy: 0.9688 - val_loss: 10.3922 - val_accuracy: 0.7050
Epoch 7/10
80/80 [==============================] - 79s 983ms/step - loss: 0.4645 - accuracy: 0.9737 - val_loss: 4.9130 - val_accuracy: 0.8200
Epoch 8/10
80/80 [==============================] - 78s 978ms/step - loss: 0.3080 - accuracy: 0.9837 - val_loss: 5.8252 - val_accuracy: 0.8250
Epoch 9/10
80/80 [==============================] - 83s 1s/step - loss: 0.1377 - accuracy: 0.9912 - val_loss: 8.0080 - val_accuracy: 0.7750
Epoch 10/10
80/80 [==============================] - 88s 1s/step - loss: 0.2952 - accuracy: 0.9850 - val_loss: 6.2213 - val_accuracy: 0.8050
Final epoch (plot to see history):
loss: 0.2952
accuracy: 0.985
val_loss: 6.221
val_accuracy: 0.805 # Pretrained model
pretrained <- application_vgg16(weights = 'imagenet',
include_top = FALSE,
input_shape = c(224, 224, 3))
# Model architecture
model <- keras_model_sequential() %>%
pretrained %>%
layer_flatten() %>%
layer_dense(units = 256, activation = "relu") %>%
layer_dense(units = 10, activation = "softmax")
summary(model)Model: "sequential_2"
________________________________________________________________________________
Layer (type) Output Shape Param #
================================================================================
vgg16 (Functional) (None, 7, 7, 512) 14714688
________________________________________________________________________________
flatten_2 (Flatten) (None, 25088) 0
________________________________________________________________________________
dense_5 (Dense) (None, 256) 6422784
________________________________________________________________________________
dense_4 (Dense) (None, 10) 2570
================================================================================
Total params: 21,140,042
Trainable params: 21,140,042
Non-trainable params: 0
________________________________________________________________________________
freeze_weights(pretrained)
summary(model)Model: "sequential_2"
_____________________________________________________________________
Layer (type) Output Shape Param #
=====================================================================
vgg16 (Functional) (None, 7, 7, 512) 14714688
_____________________________________________________________________
flatten_2 (Flatten) (None, 25088) 0
_____________________________________________________________________
dense_5 (Dense) (None, 256) 6422784
_____________________________________________________________________
dense_4 (Dense) (None, 10) 2570
=====================================================================
Total params: 21,140,042
Trainable params: 6,425,354
Non-trainable params: 14,714,688
_____________________________________________________________________
model %>% compile(loss = 'categorical_crossentropy',
optimizer = 'adam',
metrics = 'accuracy')
model_vgg16 <- model %>% fit(trainx,
trainy,
epochs = 10,
batch_size = 10,
validation_split = 0.2)
model_vgg16Epoch 1/10
80/80 [==============================] - 113s 1s/step - loss: 7.1705 - accuracy: 0.5050 - val_loss: 1.5229 - val_accuracy: 0.6250
Epoch 2/10
80/80 [==============================] - 118s 1s/step - loss: 0.2360 - accuracy: 0.9175 - val_loss: 1.2900 - val_accuracy: 0.6650
Epoch 3/10
80/80 [==============================] - 132s 2s/step - loss: 0.0421 - accuracy: 0.9837 - val_loss: 1.4543 - val_accuracy: 0.6600
Epoch 4/10
80/80 [==============================] - 122s 2s/step - loss: 0.0096 - accuracy: 0.9975 - val_loss: 1.3438 - val_accuracy: 0.6850
Epoch 5/10
80/80 [==============================] - 116s 1s/step - loss: 0.0024 - accuracy: 1.0000 - val_loss: 1.3533 - val_accuracy: 0.7100
Epoch 6/10
80/80 [==============================] - 116s 1s/step - loss: 0.0016 - accuracy: 1.0000 - val_loss: 1.3771 - val_accuracy: 0.6950
Epoch 7/10
80/80 [==============================] - 117s 1s/step - loss: 0.0012 - accuracy: 1.0000 - val_loss: 1.3868 - val_accuracy: 0.6900
Epoch 8/10
80/80 [==============================] - 119s 1s/step - loss: 8.8380e-04 - accuracy: 1.0000 - val_loss: 1.3977 - val_accuracy: 0.6850
Epoch 9/10
80/80 [==============================] - 123s 2s/step - loss: 7.0219e-04 - accuracy: 1.0000 - val_loss: 1.4090 - val_accuracy: 0.6900
Epoch 10/10
80/80 [==============================] - 124s 2s/step - loss: 5.8618e-04 - accuracy: 1.0000 - val_loss: 1.4137 - val_accuracy: 0.6900
Final epoch (plot to see history):
loss: 0.0005862
accuracy: 1
val_loss: 1.414
val_accuracy: 0.69 library(tidyverse)
# model_cnn %>% write_rds("data/model_cnn.rds")
# model_resnet50 %>% write_rds("data/model_resnet50.rds")
# model_vgg16 %>% write_rds("data/model_vgg16.rds")
model_cnn <- read_rds("data/model_cnn.rds")
model_resnet50 <- read_rds("data/model_resnet50.rds")
model_vgg16 <- read_rds("data/model_vgg16.rds")
cnn_loss <- model_cnn$metrics$loss
cnn_accuracy <- model_cnn$metrics$accuracy
resnet50_loss <- model_resnet50$metrics$loss
resnet50_accuracy <- model_resnet50$metrics$accuracy
vgg16_loss <- model_vgg16$metrics$loss
vgg16_accuracy <- model_vgg16$metrics$accuracy
tibble(cnn = cnn_accuracy,
resnet50 = resnet50_accuracy,
vgg16 = vgg16_accuracy) %>%
mutate(에포크 = 1:10) %>%
pivot_longer(cols = -에포크,
names_to = "모형",
values_to = "정확도") %>%
mutate(모형 = factor(모형, levels = c("vgg16", "resnet50", "cnn"))) %>%
ggplot(aes(x = 에포크, y = 정확도, color = 모형)) +
geom_point() +
geom_line() +
scale_y_continuous(labels = scales::percent) +
theme_light() +
labs(title = "에포크 단계별 전이학습 모형 정확도 비교")데이터 과학자 이광춘 저작
kwangchun.lee.7@gmail.com